package com.forever7776.life.core.service.impl.sys;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.forever7776.life.core.common.cache.RedisCacheOperator;
import com.forever7776.life.core.common.constants.RedisCacheWebConstants;
import com.forever7776.life.core.common.enums.SysUserEnum;
import com.forever7776.life.core.common.util.ResultVoUtil;
import com.forever7776.life.core.common.vo.SysUserSearchVO;
import com.forever7776.life.core.common.vo.UserBaseInfoVO;
import com.forever7776.life.core.entity.sys.SysUser;
import com.forever7776.life.core.mapper.sys.SysUserMapper;
import com.forever7776.life.core.service.sys.ISysUserService;
import com.forever7776.life.remote.common.vo.ResultVO;
import enums.ResultEnum;
import enums.UserStatusEnum;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 平台用户表 服务实现类
 * </p>
 *
 * @author kz
 * @since 2018-01-18
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private RedisCacheOperator redisCacheOperator;

    /**
     * 根据账号用户名和密码查询用户信息
     *
     * @param username
     * @param pwd
     * @return
     */
    @Override
    public SysUser selectOne(String username, String pwd) {
        return selectOne(new EntityWrapper<SysUser>().eq("username", username).eq("salt", pwd));
    }

    /**
     * 根据账号登录名称和邮箱查询用户信息
     *
     * @param username
     * @param email
     * @return
     */
    @Override
    public SysUser selectOneByUsernameAndEmail(String username, String email) {
        return selectOne(new EntityWrapper<SysUser>().eq("username", username).eq("email", email));
    }

    /**
     * 根据条件查询用户
     *
     * @param page
     * @param searchVO
     * @return
     */
    @Override
    public Page<SysUser> selectUsersByCondition(Page<SysUser> page, SysUserSearchVO searchVO) {
        List<SysUser> users = sysUserMapper.selectUsersByCondition(page, searchVO);
        page.setRecords(users);
        return page;
    }

    /**
     * 根据登录名查询用户
     *
     * @param username
     * @return
     */
    @Override
    public SysUser selectByUserName(String username) {
        return selectOne(new EntityWrapper<SysUser>().eq("username", username));
    }

    /**
     * 根据昵称查询用户
     *
     * @param nickname
     * @return
     */
    @Override
    public SysUser selectByNickName(String nickname) {
        return selectOne(new EntityWrapper<SysUser>().eq("nickname", nickname));
    }

    /**
     * 根据邮箱查询用户
     *
     * @param email
     * @return
     */
    @Override
    public Integer selectSysUserByEmail(String email) {
        return selectCount(new EntityWrapper<SysUser>().eq("email", email));
    }

    /**
     * 更新用户登录时间
     *
     * @param username
     * @return
     */
    @Override
    public ResultVO updateLoginTime(String username) {
        if (StringUtils.isEmpty(username)) {
            return ResultVoUtil.getFailResult("用户登录名为空！");
        }
        sysUserMapper.updateLoginTime(username);
        return ResultVoUtil.getSuccessResult(String.format("更新用户【{}】登录时间成功！", username));
    }

    /**
     * 更新用户登出时间
     *
     * @param username
     * @return
     */
    @Override
    public ResultVO updateLogoutTime(String username) {
        if (StringUtils.isEmpty(username)) {
            return ResultVoUtil.getFailResult("用户登录名为空！");
        }
        sysUserMapper.updateLogoutTime(username);
        return ResultVoUtil.getSuccessResult(String.format("更新用户【{}】登出时间成功！", username));
    }

    /**
     * 批量更新用户的状态
     *
     * @param ids
     * @param status
     * @return
     */
    @Override
    public ResultVO batchSysUserStatus(String ids, Integer status) {
        if (StringUtils.isEmpty(ids)) {
            return ResultVoUtil.getFailResult("用户ID为空！");
        }
        if (SysUserEnum.STATUS_MAP.get(status) == null) {
            return ResultVoUtil.getFailResult("状态为空！");
        }
        sysUserMapper.batchSysUserStatus(JSONObject.parseArray(ids), status);
        return ResultVoUtil.getSuccessResult(String.format("批量更新用户【{}】状态成功,状态变为：{}", ids, UserStatusEnum.STATUS_MAP.get(status)));
    }


    /**
     * 单个更新用户的状态
     *
     * @param id
     * @param status
     * @return
     */
    @Override
    public ResultVO updateSysUserStatus(String id, Integer status) {
        if (StringUtils.isEmpty(id)) {
            return ResultVoUtil.getFailResult("用户ID为空！");
        }
        if (SysUserEnum.STATUS_MAP.get(status) == null) {
            return ResultVoUtil.getFailResult("状态为空！");
        }
        sysUserMapper.updateSysUserStatus(id, status);
        return ResultVoUtil.getSuccessResult(String.format("更新用户【{}】状态成功,状态变为：{}", id, UserStatusEnum.STATUS_MAP.get(status)));
    }

    /**
     * 注册账号校验
     *
     * @param sysUser
     * @return
     */
    @Override
    public ResultVO checkRegisterForm(SysUser sysUser) {
        ResultVO result = new ResultVO();
        if (sysUser == null || StringUtils.isEmpty(sysUser.getUsername()) || StringUtils.isEmpty(sysUser.getEmail())) {
            result.setCode(ResultEnum.STATUS.FAIL.getCode());
            result.setMsg(" 参数为空");
            return result;
        }
        if (selectByUserName(sysUser.getUsername()) != null) {
            result.setCode(ResultEnum.STATUS.FAIL.getCode());
            result.setMsg(" 该昵称已经存在");
            return result;
        }
        if (selectSysUserByEmail(sysUser.getEmail()) != 0) {
            result.setCode(ResultEnum.STATUS.FAIL.getCode());
            result.setMsg(" 该邮箱已经注册");
            return result;
        }
        String pwd_reg = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,32}$";
        if (!sysUser.getPassword().matches(pwd_reg)) {
            result.setCode(ResultEnum.STATUS.FAIL.getCode());
            result.setMsg(" 请输入6~32位数字和英文结合的密码~");
            return result;
        }
        result.setCode(ResultEnum.STATUS.SUCCESS.getCode());
        result.setMsg("注册成功！");
        return result;
    }

    /**
     * 根据时间类型查询注册用数据
     *
     * @param type
     * @return
     */
    @Override
    public Integer selectRegisterCountByTimeType(String type) {
        return sysUserMapper.selectRegisterCountByTimeType(type);
    }

    /**
     * 根据时间类型查询登录用数据
     *
     * @param type
     * @return
     */
    @Override
    public Integer selectLoginCountByTimeType(String type) {
        return sysUserMapper.selectLoginCountByTimeType(type);
    }

    /**
     * 查询用户量
     *
     * @return
     */
    @Override
    public Integer selectCount() {
        return sysUserMapper.selectCount(new EntityWrapper<SysUser>());
    }

    /**
     * 根据用户登录名查询用户ID
     *
     * @param username
     * @return
     */
    @Override
    public String selectUserIdByUsername(String username) {
        return sysUserMapper.selectUserIdByUsername(username);
    }

    /**
     * 修改密码
     *
     * @param userId
     * @param newPwd
     * @return
     */
    @Override
    public ResultVO cpwd(String userId, String newPwd) {
        String newSat = DigestUtils.md5Hex(newPwd);
        sysUserMapper.cpwd(userId, newPwd, newSat);
        return ResultVoUtil.getSuccessResult("修改密码成功");
    }

    /**
     * 查看用户数据，先从redis中获取，如果没有则从数据库中查询
     *
     * @param userId
     * @return
     */
    @Override
    public UserBaseInfoVO selectUserBaseInfoById(String userId) {
        String object = redisCacheOperator.getCacheObject(RedisCacheWebConstants.LOGIN_USER + userId);
        UserBaseInfoVO info = JSONObject.parseObject(object, UserBaseInfoVO.class);
        if (info != null) {
            return info;
        }
        info = sysUserMapper.selectUserBaseInfoById(userId);
        redisCacheOperator.setCacheObject(RedisCacheWebConstants.LOGIN_USER + userId, info.toString(), 1, TimeUnit.HOURS);
        return info;
    }

    @Override
    public List<UserBaseInfoVO> selectUserBaseInfos(List<String> userIds) {
        return sysUserMapper.selectUserBaseInfos(userIds);
    }
}
